home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / boot / bind_namesii.lha / AssignNode.c next >
C/C++ Source or Header  |  1995-09-14  |  6KB  |  294 lines

  1. /* $Header: Src:Dcc/BindNames/rcs/AssignNode.c,v 1.5 1995/06/21 17:24:04 cmh Exp cmh $
  2.  *
  3.  * BindNamesII: Handy assign/path maker.
  4.  * Copyright (C) 1994-95  Magnus Holmgren <cmh@augs.se>
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include <exec/types.h>
  22. #include <exec/memory.h>
  23. #include <dos/exall.h>
  24.  
  25. #include <clib/alib_protos.h>
  26. #include <clib/dos_protos.h>
  27. #include <clib/exec_protos.h>
  28. #include <clib/utility_protos.h>
  29.  
  30. #ifdef __GNUC__
  31. #include <inline/dos.h>
  32. #include <inline/exec.h>
  33. #include <inline/utility.h>
  34. #endif
  35.  
  36. #include <string.h>
  37. #include "assignnode.h"
  38.  
  39. #define Prototype extern
  40.  
  41. #include "proto.h"
  42. #include "macros.h"
  43.  
  44. #define ANSI_WHITE_ON       "\x9b" "2m"
  45. #define ANSI_WHITE_OFF      "\x9b" "22m"
  46.  
  47.  
  48. /* Duplicate a string. Use FreeVec() to free the duplicate. */
  49. STRPTR
  50. StrDup( STRPTR string )
  51. {
  52.     STRPTR    newString;
  53.  
  54.     if( ( newString = AllocVec( strlen( string ) + 1, MEMF_ANY ) ) )
  55.     {
  56.         strcpy( newString, string );
  57.     }
  58.  
  59.     return( newString );
  60. }
  61.  
  62.  
  63. /* Scans the specified list of AssignNodes after an AssignNode with
  64.  * the specified name. Case is ignored.
  65.  */
  66. Prototype struct AssignNode *FindAssignNode( struct MinList *, STRPTR );
  67. struct AssignNode *
  68. FindAssignNode( struct MinList *start, STRPTR name )
  69. {
  70.     struct AssignNode    *node, *next;
  71.  
  72.     FOREACHNODE( start, node, next )
  73.     {
  74.         if( !Stricmp( node->Name, name ) )
  75.         {
  76.             break;
  77.         }
  78.     }
  79.  
  80.     return( node->Node.mln_Succ ? node : NULL );
  81. }
  82.  
  83.  
  84. /* Simply free a PathNode. If NULL, do nothing. */
  85. Prototype VOID FreePathNode( struct PathNode * );
  86. VOID
  87. FreePathNode( struct PathNode *node )
  88. {
  89.     if( node )
  90.     {
  91.         FreeVec( node->Name );
  92.         FreeVec( node );
  93.     }
  94. }
  95.  
  96.  
  97. /* Create a PathNode with the specified name and priority. */
  98. struct PathNode *
  99. AllocPathNode( STRPTR name, BYTE pri )
  100. {
  101.     struct PathNode    *node;
  102.  
  103.     if( ( node = AllocVec( sizeof( struct PathNode ), MEMF_CLEAR ) ) )
  104.     {
  105.         node->Node.ln_Pri = pri;
  106.  
  107.         if( !( node->Name = StrDup( name ) ) )
  108.         {
  109.             FreeVec( node );
  110.             node = NULL;
  111.         }
  112.     }
  113.  
  114.     return( node );
  115. }
  116.  
  117.  
  118. /* Simply free an AssignNode. If NULL, do nothing. */
  119. Prototype VOID FreeAssignNode( struct AssignNode * );
  120. VOID
  121. FreeAssignNode( struct AssignNode *node )
  122. {
  123.     if( node )
  124.     {
  125.         struct PathNode *pathNode, *next;
  126.  
  127.         FOREACHNODE( &node->Path, pathNode, next )
  128.         {
  129.             FreePathNode( pathNode );
  130.         }
  131.  
  132.         FreeVec( node->Alias );
  133.         FreeVec( node->Name );
  134.         FreeVec( node );
  135.     }
  136. }
  137.  
  138.  
  139. /* Create an AssignNode with the specified attributes. Scans the list for
  140.  * nodes with the same name. If found, the path targets will be added to
  141.  * the old node.
  142.  */
  143. Prototype struct AssignNode *AllocAssignNode( struct MinList *, STRPTR, STRPTR *, BYTE, STRPTR, WORD, WORD );
  144. struct AssignNode *
  145. AllocAssignNode(
  146.     struct MinList    *list,
  147.     STRPTR        name,
  148.     STRPTR        *path,
  149.     BYTE        pri,
  150.     STRPTR        alias,
  151.     WORD        type,
  152.     WORD        flags )
  153. {
  154.     struct AssignNode    *assignNode;
  155.  
  156.     /* Try to locate previous node */
  157.     assignNode = FindAssignNode( list, name );
  158.  
  159.     if( assignNode || ( assignNode = AllocVec( sizeof( struct AssignNode ), MEMF_CLEAR ) ) )
  160.     {
  161.         struct PathNode *pathNode;
  162.         BOOL    add = FALSE;
  163.  
  164.         /* Adding to a previous node? */
  165.         if( !assignNode->Name )
  166.         {
  167.             /* Nope, init new list */
  168.             NewList( ( struct List * ) &( assignNode->Path ) );
  169.             add = TRUE;
  170.  
  171.                     if( !( assignNode->Name = StrDup( name ) ) )
  172.             {
  173.                 goto error;     /* This kind of goto:s can be accepted sometimes.. :) */
  174.             }
  175.         }
  176.  
  177.         if( alias && !assignNode->Alias && !( assignNode->Alias = StrDup( alias ) ) )
  178.         {
  179.             goto error;
  180.         }
  181.  
  182.         /* Add the targets */
  183.         for( ; *path; ++path )
  184.         {
  185.             if( ( pathNode = AllocPathNode( *path, pri ) ) )
  186.             {
  187.                 Enqueue( ( struct List * ) &( assignNode->Path ),
  188.                     ( struct Node * ) pathNode );
  189.             }
  190.             else
  191.             {
  192.                 goto error;
  193.             }
  194.         }
  195.  
  196.         assignNode->AssignType = type;
  197.         assignNode->Flags |= flags;
  198.  
  199.         if( add )
  200.         {
  201.             AddTail( ( struct List * ) list, ( struct Node * ) assignNode );
  202.         }
  203.     }
  204.  
  205.     return( assignNode );
  206.  
  207. error:    FreeAssignNode( assignNode );
  208.     return( NULL );
  209. }
  210.  
  211.  
  212. /* Free all nodes on the list, assuming they are AssignNodes. */
  213. Prototype VOID FreeAssignList( struct MinList * );
  214. VOID
  215. FreeAssignList( struct MinList *list )
  216. {
  217.     struct AssignNode    *node, *next;
  218.  
  219.     FOREACHNODE( list, node, next )
  220.     {
  221.         FreeAssignNode( node );
  222.     }
  223.  
  224.     NewList( ( struct List * ) list );
  225. }
  226.  
  227.  
  228. /* Print the assinglist, in an Assign-like manner.
  229.  * Also prints any accumulated errors.
  230.  */
  231. Prototype VOID PrintAssignList( struct MinList * );
  232. VOID
  233. PrintAssignList( struct MinList *list )
  234. {
  235.     struct AssignNode    *node, *nextAssign;
  236.     struct PathNode        *pathNode, *nextPath;
  237.     BOOL    first;
  238.  
  239.     FOREACHNODE( list, node, nextAssign )
  240.     {
  241.         STRPTR  str;
  242.  
  243.         /* Print assign name */
  244.         Printf( ( node->Flags & ANF_ADD ) ? "%-18s+ " : "%-20s", ( LONG ) node->Name );
  245.         first = TRUE;
  246.  
  247.         /* Print the target(s) */
  248.         FOREACHNODE( &node->Path, pathNode, nextPath )
  249.         {
  250.             switch( node->AssignType )
  251.             {
  252.                 case ASN_DEFER:
  253.                     str = "<%s>\n";
  254.                     break;
  255.  
  256.                 case ASN_PATH:
  257.                     str = "[%s]\n";
  258.                     break;
  259.  
  260.                 default:
  261.                     str = first ? "%s\n" : "\t\t  + %s\n";
  262.             }
  263.  
  264.             Printf( str, ( LONG ) pathNode->Name );
  265.             first = FALSE;
  266.         }
  267.  
  268.         /* Handle the errors. */
  269.         if( node->Flags & ( ANF_FAILED | ANF_LOOP | ANF_BAD | ANF_BADPARENT ) )
  270.         {
  271.             Printf( "  " ANSI_WHITE_ON "Failed because: " );
  272.  
  273.             if( node->Flags & ANF_FAILED )
  274.             {
  275.                 PrintFault( node->IoErr, NULL );
  276.             }
  277.             else if( node->Flags & ANF_LOOP )
  278.             {
  279.                 Printf( "part of an assign loop" );
  280.             }
  281.             else if( node->Flags & ANF_BADPARENT )
  282.             {
  283.                 Printf( "parent assign failed" );
  284.             }
  285.             else
  286.             {
  287.                 Printf( "bad assign (multiple targets for DEFER or PATH)" );
  288.             }
  289.  
  290.             Printf( ANSI_WHITE_OFF "\n" );
  291.         }
  292.     }
  293. }
  294.